﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.Designtime.Metadata;
using CPPEI.Coolzon.ServiceProxy.DesignServiceRef;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DT = CPPEI.Coolzon.Designtime.Metadata;

namespace CPPEI.Coolzon.Designer.Views
{
    /// <summary>
    /// 获取最新版本的线程，
    /// 从服务器获取项目列表与本地的比较，删除本地多余的，获取服务器上新增的和
    /// </summary>
    static class GetLatestVersionThread
    {
        private static bool s_isRunning = false;
        private static Thread s_thread;
        private static Action<Guid, string, int, int> s_progress;
        private static Action<bool, int, int> s_completed;
        private static Guid s_solutionId;

        /// <summary>
        /// solutiontreeviewNode状态在线程中修改
        /// </summary>
        /// <param name="solutionId">方案编号</param>
        /// <param name="progress">项目ID, 项目名称，撤销进度，总数量</param>
        /// <param name="completed">是否出现错误，成功数量，总数量</param>
        public static bool Start(Guid solutionId, Action<Guid, string, int, int> progress, Action<bool, int, int> completed)
        {
            if (s_isRunning)
            {
                return false;
            }

            s_solutionId = solutionId;
            s_progress = progress;
            s_completed = completed;
            s_isRunning = true;
            s_thread = new Thread(Running);
            s_thread.Start();
            return true;
        }

        public static void Stop()
        {
            if (s_isRunning)
            {
                s_thread.Abort();
                s_isRunning = false;
                s_thread = null;
            }
        }

        private static void Running()
        {
            Logger.DebugToTag(Library.LogTAG, "GetLatestVersionThread Running");
            int total = 0;
            int progress = 0;
            bool hasError = false;

            CPPEI.Coolzon.ServiceProxy.DesignServiceRef.DesignServiceClient dsClient =
                CPPEI.Coolzon.ServiceProxy.DesignServiceProxyManager.Create();

            string workspacePath = UIContext.Current.LocalWorkSpace.LocalPath;

            CPPEI.Coolzon.ServiceProxy.DesignServiceRef.GetItemSummaryListRequest request = new GetItemSummaryListRequest(s_solutionId, UIContext.Current.Token);
            CPPEI.Coolzon.ServiceProxy.DesignServiceRef.ListResultOf_ItemSummary result = dsClient.GetSolutionItemSummaries(request);

            if (result.IsSuccess)
            {
                total = result.Data.Length;

                // 创建方案目录
                string solutionDir = LocalStorage.GetSolutionDir(workspacePath, s_solutionId);
                if(!Directory.Exists(solutionDir))
                {
                    Directory.CreateDirectory(solutionDir);
                    Logger.DebugToTag(Library.LogTAG, "创建方案目录:{0}", solutionDir);
                }

                for (int index = 0; index < result.Data.Length; index++)
                {
                    CPPEI.Coolzon.ServiceProxy.DesignServiceRef.ItemSummary item = result.Data[index];

                    // 判断本地是否有这个文件
                    VSFile vsFile = VSFileMgr.GetFile(workspacePath, s_solutionId, item.Id);
                    if (vsFile == null || vsFile.Version < item.Version)
                    {
                        #region 获取最新的保存在本地
                        CPPEI.Coolzon.ServiceProxy.DesignServiceRef.GetLatestVersionRequest tlvRequest = new ServiceProxy.DesignServiceRef.GetLatestVersionRequest();
                        tlvRequest.Token = UIContext.Current.Token;
                        tlvRequest.SolutionId = s_solutionId;
                        tlvRequest.Id = result.Data[index].Id;

                        CPPEI.Coolzon.ServiceProxy.DesignServiceRef.GetLatestVersionResponse tlvResponse = dsClient.GetLatestVersion(tlvRequest);
                        if (tlvResponse.IsSuccess)
                        {
                            if (tlvResponse.Content != null)
                            {
                                // 获取本地的文件，然后删除，并用服务器回来的文件替换
                                if (tlvResponse.ItemType == CPPEI.Coolzon.Designer.Views.Models.Constant.ItemType.Solution)
                                {
                                    #region 方案文件
                                    string filePath = LocalStorage.GetSolutionFileAbsolutePath(workspacePath, s_solutionId);
                                    if (File.Exists(filePath))
                                    {
                                        System.IO.File.Delete(filePath);
                                        Logger.DebugToTag(Library.LogTAG, "删除方案文件:{0}", filePath);
                                    }
                                    // 保存新的文件
                                    using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write))
                                    {
                                        // 我们不用对两个流对象进行读写，只要复制流就OK  
                                        tlvResponse.Content.CopyTo(fileStream);
                                        fileStream.Flush();
                                    }
                                    Logger.DebugToTag(Library.LogTAG, "创建方案文件:{0}", filePath);
                                    #endregion
                                }
                                else if (tlvResponse.ItemType == CPPEI.Coolzon.Designer.Views.Models.Constant.ItemType.Scene)
                                {
                                    #region 场景文件
                                    string filePath = LocalStorage.GetSceneFileAbsolutePath(workspacePath, s_solutionId, tlvResponse.ItemId);
                                    if(File.Exists(filePath))
                                    {
                                        System.IO.File.Delete(filePath);
                                        Logger.DebugToTag(Library.LogTAG, "删除场景文件:{0}", filePath);
                                    }
                                    // 保存新的文件
                                    using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write))
                                    {
                                        // 我们不用对两个流对象进行读写，只要复制流就OK  
                                        tlvResponse.Content.CopyTo(fileStream);
                                        fileStream.Flush();
                                        Logger.DebugToTag(Library.LogTAG, "创建场景文件:{0}", filePath);
                                    }
                                    #endregion
                                }
                                else if(tlvResponse.ItemType == CPPEI.Coolzon.Designer.Views.Models.Constant.ItemType.Folder)
                                {
                                    // 目录
                                    continue;
                                }
                                else
                                {
                                    // 资源文件
                                    string filePath = LocalStorage.GetResourceFileAbsolutePath(workspacePath, s_solutionId, tlvResponse.ItemId, tlvResponse.ItemExtension);
                                    if (File.Exists(filePath))
                                    {
                                        System.IO.File.Delete(filePath);
                                        Logger.DebugToTag(Library.LogTAG, "删除资源文件:{0}", filePath);
                                    }
                                    // 保存新的文件
                                    using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write))
                                    {
                                        // 我们不用对两个流对象进行读写，只要复制流就OK  
                                        tlvResponse.Content.CopyTo(fileStream);
                                        fileStream.Flush();
                                        Logger.DebugToTag(Library.LogTAG, "创建资源文件:{0}", filePath);
                                    }
                                }
                            }
                            // 更新本地的文件项目状态
                            VSFileMgr.GoToCheckIn(workspacePath, s_solutionId, tlvResponse.ItemId, tlvResponse.ItemFolderId, tlvResponse.ItemVersion);
                            if (tlvResponse.IsEditing)
                            {
                                if(string.Equals(tlvResponse.Editor, UIContext.Current.UserAccount))
                                {
                                    VSFileMgr.GoToCheckOut(workspacePath, s_solutionId, tlvResponse.ItemId);
                                }
                                else
                                {
                                    VSFileMgr.GoToOthersLocked(workspacePath, s_solutionId, tlvResponse.ItemId);
                                }
                            }
                            Logger.DebugToTag(Library.LogTAG, "设置本地状态为签入,item:{0}, folder:{1}, version:{2}",
                                tlvResponse.ItemId,
                                tlvResponse.ItemFolderId,
                                tlvResponse.ItemVersion);

                            progress++;

                            s_progress(tlvResponse.ItemId, tlvResponse.ItemName, progress, total);
                        }
                        else
                        {
                            Logger.ErrorToTag(Library.LogTAG, string.Format("撤销Name:{0},Id:{1}失败", tlvResponse.ItemName, tlvResponse.ItemId));
                            hasError = true;
                            break;
                        }
                        #endregion
                    }
                }
            }

            dsClient.Close();

            s_completed(hasError, progress, total);
            s_isRunning = false;
            s_thread = null;

            Logger.DebugToTag(Library.LogTAG, "GetLatestVersionThread Finished");
        }
    }
}
